home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / progjrn / pj_7_3a.arc / DELIM.C < prev    next >
C/C++ Source or Header  |  1989-04-19  |  6KB  |  320 lines

  1. /*
  2.  *  delim.c    - a dbASE3 filter
  3.  *
  4.  *  takes a text file with fields delimited with a 'delim' char
  5.  *  and creates a file a comma delimited file with double quotes '"'
  6.  *  around all fields so dBASE3 can import it
  7.  *
  8.  *  Author:    M. Steven Baker
  9.  *  Last Revision:        October 17, 1988
  10.  */
  11.  
  12. /*     Macros for constant definitions */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <ctype.h>
  17. #include <string.h>
  18.  
  19. #ifndef FILENAME_MAX
  20. #define FILENAME_MAX    68
  21. #endif
  22.  
  23. FILE *infp;
  24. FILE *outfp = stdout;                /* our file pointers */
  25.  
  26. char  infile[FILENAME_MAX] = "";    /* our file names */
  27. char outfile[FILENAME_MAX] = "";
  28.  
  29. int verbose = 0;
  30. int noquote = 0;
  31. int    errflag = 0;
  32.  
  33. char delim = '\t';            /* default delimiter character */
  34. char new_quote = ' ';        /* default new quote character */
  35. int fieldflag = 0;            /* logical flag for field delimited cut */
  36. int colflag = 0;            /* logical flag fro column oriented cut */
  37. int sflag = 0;                /* the cut -s flag -- not implemented yet */
  38.  
  39.  
  40. char *pgm = "delim";        /* our program name */
  41.  
  42. /*
  43.     main to open the files for scrub()
  44.     and handle invocation errors.
  45. */
  46.  
  47. void usage();
  48.  
  49. char *help_msg[] =
  50. {
  51.     "DELIM takes an ascii text file with fields separated by a unique",
  52.     "delimiter character, and substitutes commas, and quotes for dBASE3.",
  53.     "The following options may be used singly or in combination:",
  54.     "-d delimiter \t field delimiter character (default = tab)",
  55.     "-o filename\t create output text file (default stdout)",
  56.     "-q char\t\t replace any double quotes with char (. stands for space)",
  57.     "\t\t so dBASE won't get confused",
  58.     "-v\t\t verbose mode"
  59. };
  60.  
  61.  
  62. main(argc,argv)
  63. int argc;
  64. char **argv;
  65. {
  66.     int    ch;                    /* variable for getopt */
  67.  
  68.     extern int getopt();
  69.     extern char *optarg;
  70.     extern int optind, opterr;
  71.  
  72.  
  73.     /* process command-line arguments */
  74.     opterr = 0;    /* first turn off error messages from getopt */
  75.     while ((ch = getopt(argc,argv, "vd:o:q:")) != EOF)
  76.     {
  77.         switch (ch) {
  78.  
  79.             case 'd':
  80.                 delim = *optarg;
  81.                 break;
  82.             case 'v':
  83.                 verbose = 1;
  84.                 break;
  85.             case 'o':        /* output specifed cut text file */
  86.                 strcpy(outfile, optarg);
  87.                 outfp = NULL;
  88.                 break;
  89.             case 'q':
  90.                 noquote = 1;
  91.                 new_quote = *optarg;
  92.                 if (new_quote == '.')
  93.                     new_quote = ' ';
  94.                 break;
  95.             default:        /* unknown option */
  96.                 errflag++;
  97.                 break;
  98.             }
  99.         }
  100.     if (errflag || !(argc-optind) )
  101.     {
  102.         usage(pgm);
  103.         exit(1);
  104.     }
  105.  
  106.     if ( convert(argc - optind, argv += optind) )    /* did we have errors? */
  107.         exit (1);
  108.  
  109.     exit(0);
  110. }
  111.  
  112. /*
  113.  *    convert -  process each filename or standard input
  114.  */
  115.  
  116. int convert(ac, av)
  117. int    ac;
  118. char **av;
  119. {
  120.     int    ch, errcount = 0;
  121.     char *p;
  122.  
  123.     for (; ac > 0; --ac, ++av)
  124.     {
  125.         p = *av;
  126.         strcpy(infile,p);            /* store input data filename */
  127.         if ((infp = fopen (infile,"rt")) == NULL)
  128.         {
  129.             fprintf(stderr,"%s: ERROR opening input file: %s\n",
  130.             pgm,infile);
  131.             continue;
  132.         }
  133.  
  134.         if (outfp != stdout)
  135.         {
  136.             if ((outfp = fopen (outfile,"wt")) == NULL)
  137.             {
  138.                 fprintf(stderr,"%s: ERROR opening output file: %s\n",outfile);
  139.                 fclose (infp);
  140.                 continue;
  141.             }
  142.         }
  143.         if (dodelim(infp,outfp)== EOF)
  144.         {
  145.             fprintf(stderr,"%s: Error converting file: %s\n",pgm,infile);
  146.             fclose(infp);
  147.             fclose(outfp);
  148.             errcount++;
  149.             continue;
  150.         }
  151.         fclose(infp);
  152.         if (fclose(outfp) == EOF)
  153.         {
  154.             fprintf(stderr,"%s: Error closing output file: %s\n",pgm,
  155.                 outfile);
  156.             errcount++;
  157.             continue;
  158.         }
  159.     }                    /* end of for loop */
  160.     return (errcount);
  161. }
  162.  
  163. #define BEGIN    0
  164. #define INFIELD 1
  165. #define DELIM    2
  166.  
  167. /*
  168.     procedure dodelim -- copy file to file replacing delimeters
  169. */
  170.  
  171. dodelim(fp1,fp2)
  172. FILE *fp1;        /* the input file pointer */
  173. FILE *fp2;        /* the output file pointer */
  174.  
  175. {
  176.     int c;            /* 1 char buffer */
  177.     int    i,state, last;
  178.  
  179.     long count = 0;        /* count of characters processed */
  180.     long linecnt = 0;   /* number of lines processed */
  181.     long quotecnt = 0;    /* count of quote characters replaced */
  182.  
  183.     state = BEGIN;
  184.     while( (c = getc(fp1)) != EOF)
  185.     {
  186.         count++;
  187.         switch (state)
  188.         {
  189.             case BEGIN:
  190.                 if (c == delim)
  191.                 {
  192.                     fputc('"',fp2);        /* emit the first " */
  193.                     fputc('"',fp2);
  194.                     state = DELIM;
  195.                     last = DELIM;
  196.                 }
  197.                 else
  198.                 {
  199.                     if (c == '\n')
  200.                     {
  201.                         fputc (c, fp2);
  202.                         state = BEGIN;
  203.                         linecnt++;
  204.                     }
  205.                     else                    /* got a starting CHAR */
  206.                     {
  207.                         fputc('"',fp2);        /* emit the first " */
  208.                         if (noquote)
  209.                         {
  210.                             if ( c == '"')  
  211.                             {
  212.                                 c = new_quote;
  213.                                 quotecnt++;
  214.                             }
  215.                         }
  216.                         fputc (c, fp2);
  217.                         state = INFIELD;
  218.                     }
  219.                 }
  220.                 break;
  221.             case INFIELD:
  222.                 if (c == delim)
  223.                 {
  224.                     fputc('"',fp2);        /* emit the first " */
  225.                     state = DELIM;
  226.                     last = DELIM;
  227.                 }
  228.                 else
  229.                 {
  230.                     if (c == '\n')
  231.                     {
  232.                         fputc ('"',fp2);
  233.                         fputc (c, fp2);
  234.                         state = BEGIN;
  235.                         linecnt++;
  236.                     }
  237.                     else                    /* got a CHAR */
  238.                     {
  239.                         if (noquote)
  240.                         {
  241.                             if ( c == '"')  
  242.                             {
  243.                                 c = new_quote;
  244.                                 quotecnt++;
  245.                             }
  246.                         }
  247.                         fputc (c, fp2);
  248.                     }
  249.                 }
  250.                 break;
  251.             case DELIM:
  252.                 if (c == delim)
  253.                 {
  254.                     if (last == DELIM)
  255.                     {
  256.                         fputc(',',fp2);
  257.                         fputc('"',fp2);
  258.                         fputc('"',fp2);
  259.                     }
  260.                     else
  261.                     {
  262.                         fputc('"',fp2);        /* then emit the first " */
  263.                         state = DELIM;
  264.                         last = DELIM;
  265.                     }
  266.                 }
  267.                 else
  268.                 {
  269.                     if (c == '\n')
  270.                     {
  271.                         fputc (c, fp2);
  272.                         state = BEGIN;
  273.                         linecnt++;
  274.                     }
  275.                     else                    /* got a CHAR */
  276.                     {
  277.                         fputc (',',fp2);
  278.                         fputc ('"',fp2);
  279.                         if (noquote)
  280.                         {
  281.                             if ( c == '"')  
  282.                             {
  283.                                 c = new_quote;
  284.                                 quotecnt++;
  285.                             }
  286.                         }
  287.                         fputc (c, fp2);
  288.                         state = INFIELD;
  289.                     }
  290.                 }
  291.                 break;
  292.             default:
  293.                 return (EOF);
  294.         }
  295.     }
  296.     if (verbose)
  297.     {
  298.         printf("\n  Characters processed: %ld   Lines processed %ld\n",count,linecnt);
  299.         if (noquote && quotecnt > 0)
  300.             printf("  Quote characters replaced: %ld\n",quotecnt);
  301.     }
  302.     return (0);
  303. }
  304.  
  305. /*
  306.  *    usage - display an abbreviated help usage message
  307.  */
  308.  
  309. void usage(pname)
  310. char *pname;
  311. {
  312.     int i, n = sizeof(help_msg)/sizeof (char *);
  313.  
  314.     fprintf(stderr,"Usage: %s [options] file...\n\n",pname);
  315.     for (i = 0; i < n; ++i)
  316.         fprintf(stderr, "%s\n",help_msg[i]);
  317.     return;
  318. }
  319.  
  320.